package cranim.simulation;

import cranim.Constants;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Benedikt
 */
public class Simulation implements Constants{
    
    private Player attacker, defender, genAttacker, genDefender;
    private ArrayList<SimCase> cases;
    private int simrounds;
    
    public Simulation(Player attacker, Player defender, int simrounds){
        this.simrounds = simrounds;
        this.attacker = attacker;
        this.genAttacker = attacker.clonePlayer();
        this.defender = defender;
        this.genDefender = defender.clonePlayer();
        cases = new ArrayList<>();
    }
    
    public ArrayList<SimCase> run(){
        for(int simround = 0; simround < simrounds; simround++){
            SimCase simroundcase = new SimCase(attacker, defender);
            //System.out.println("New Simulation round: "+simround);
            for(int round = 1; round <= MAX_ROUNDS; round++){
                RoundResult roundresult = playRound(round);
                simroundcase.addRound(roundresult);
                //Attacker has no units left
                if(attacker.getFleet().isEmtpy()){
                    //System.out.println("Attacker has no units left");
                    break;
                }
                //Defender has no units left
                else if(defender.getFleet().isEmtpy()){
                    //System.out.println("Defender has no units left");
                    break;
                }
            }
            //Result after all rounds
            RoundResult roundresult = new RoundResult(-1, attacker, defender);
            simroundcase.addRound(roundresult);
            cases.add(simroundcase);
            restorePlayers();
        }
        return cases;
    }
    
    public RoundResult playRound(int round){
        //System.out.println("Round: "+round);
        
        //Recharge shields
        roundInit();
        
        RoundResult roundresult = new RoundResult(round, attacker, defender);
        
        //Attacker shoots first
        for(int unittype_a = 0; unittype_a < ATTACKER_UNITS; unittype_a++){
            List<Unit> runits = attacker.getFleet().getUnitsOfType(unittype_a);
            if(!runits.isEmpty()){
                for(int u = 0; u < runits.size(); u++){
                    Shot shot = runits.get(u).shoot(defender.getFleet());
                    roundresult.addAttackerShot(shot);
                }
            }
        }
        //Defender shoots next
        for(int unittype_d = 0; unittype_d < DEFENDER_UNITS; unittype_d++){
            List<Unit> runits = defender.getFleet().getUnitsOfType(unittype_d);
            if(!runits.isEmpty()){
                for(int u = 0; u < runits.size(); u++){
                    Shot shot = runits.get(u).shoot(attacker.getFleet());
                    roundresult.addDefenderShot(shot);
                }
            }
        }
        //Remove destroyed units
        roundEnd();
        return roundresult;
    }

    private void roundInit() {
         attacker.getFleet().recharge(attacker.getShieldTech());
         defender.getFleet().recharge(defender.getShieldTech());
    }
    
    private void roundEnd() {
        attacker = attacker.clonePlayer();
        defender = defender.clonePlayer();
        attacker.getFleet().removeDestroyed();
        defender.getFleet().removeDestroyed();
    }
    
    public Player getAttacker(){
        return attacker;
    }
        
    public Player getDefender(){
        return defender;
    }
    
    public void restorePlayers(){
        attacker = genAttacker.clonePlayer();
        defender = genDefender.clonePlayer();
    }
    
}
